import uiUtils from './uiUtils'
import Vue from 'vue'

// 这个bus对象用作全局的事件总线,用于一些特殊场景下的组件通讯
export const bus = new Vue()
export default {
  merge (obj) {
    for (const [key, value] of Object.entries(obj)) {
      this[key] = value
    }
  },
  ...uiUtils,
  url2Obj (url = document.URL) {
    const q = {}
    url.replace(/([^?&=]+)=([^&]+)/g, (_, k, v) => (q[k] = v))
    return q
  },
  getUrlParam (key) {
    return this.url2Obj()[key]
  },
  // 反转对象的key-value
  reverse (source) {
    const re = {}
    for (const key of Object.keys(source)) {
      re[source[key]] = key
    }
    return re
  },
  // 对象转为数组
  objToArr (obj = {}, labelField = 'label', valueField = 'value') {
    const arr = []
    for (const key of Object.keys(obj)) {
      arr.push({ [labelField]: key, [valueField]: obj[key] })
    }
    return arr
  },
  simpleClone (obj) {
    return obj ? JSON.parse(JSON.stringify(obj)) : null
  },
  // 下划线转换驼峰
  toHump (name) {
    return name.replace(/_(\w)/g, function (all, letter) {
      return letter.toUpperCase()
    })
  },
  // 驼峰转换下划线
  toLine (name) {
    return name.replace(/([A-Z])/g, '_$1').toLowerCase()
  },
  /**
   * 通过传入的children字段名，将多层级的对象打平为一个数组
   * @param {T} source
   * @param {string} children
   * @returns {T[]}
   * 例如  [{id: 1, children: [{id: 2}]}] => [{id: 1}, {id: 2}]
   */
  flatObject (source, children = 'children', parentKey = 'parentId', idKey = 'id') {
    const re = []
    this.flatObjectDo(source, children, re, undefined, parentKey, idKey)
    return re
  },
  flatObjectDo (source, children, re, parentId, parentKey, idKey) {
    source.forEach((s) => {
      if (parentId) {
        s[parentKey] = parentId
      }
      re.push(s)
      if (s[children]) {
        this.flatObjectDo(s[children], children, re, s[idKey], parentKey, idKey)
        delete s[children]
      }
    })
  },
  /* 数组转树
  * @param source
  * @param parentIdVal
  * @param id
  * @param parentId
  * @returns {*}
  */
  list2Tree (source, parentIdVal = undefined, id = 'id', parentId = 'parentId', level = -1) {
    const target = source.filter((s) => s[parentId] === parentIdVal)
    target.forEach((t) => {
      delete t.children
      if (t[id]) {
        const children = this.list2Tree(source, t[id], id, parentId)
        if (children.length) {
          t.children = children
        }
      }
    })
    return target
  },
  mergeList (arr1 = [], arr2 = [], key = 'id') {
    return [...arr1, ...arr2].filter((item, index, arr) => {
      return index === arr.findIndex(a => a[key] === item[key])
    })
  },
  // 空对象判断
  isEmptyObject (obj) {
    return Object.keys(obj).length <= 0
  },
  // 日期判断
  isDate (obj) {
    return Object.prototype.toString.call(obj) === '[object Date]'
  },
  isObj (obj) {
    return Object.prototype.toString.call(obj) === '[object Object]'
  }
}
